package github.saukiya.sxattribute.util.nms;

import org.bukkit.Bukkit;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class NMSUtils {

    public static NMSBase nmsBase;

    static {
        try {

            String version = getVersion();
            switch (version){
                case "v1_8_R3":
                case "v1_10_R1":
                    nmsBase =  new NMS_v1_8_R3();
                    break;
                case "v1_11_R1":
                    nmsBase = new NMS_v1_12_R1();
                    break;
                case "v1_13_R2":
                    nmsBase = new NMS_v1_13_R1();
                    break;
                case "v1_16_R2":
                case "v1_16_R1":
                    nmsBase = new NMS_v1_16_R1();
                    break;
                default:
                    nmsBase =  (NMSBase) Class.forName("github.saukiya.sxattribute.util.nms.NMS_"+getVersion()).newInstance();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static String getVersion(){
        String packet = Bukkit.getServer().getClass().getPackage().getName();
        return packet.substring(packet.lastIndexOf('.') + 1);
    }

    public static NMSBase getNMSBase() throws Exception{
        return nmsBase;
    }

    public static Object getFiled(Object data,String name){
        Object o = null;
        try {
            Field field = data.getClass().getDeclaredField(name);
            field.setAccessible(true);
            o = field.get(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return o;
    }

    public static Method getMethod(Object o,String name,Class<?>... classs){
        try {
            return o.getClass().getDeclaredMethod(name,classs);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return null;
    }


    public static Object getMethodReturnValue(Object o,Method method,Class<?>... classes){
        try {
            method.setAccessible(true);
            return method.invoke(o,classes);
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }

}
